package com.yootk.servlet;

import jakarta.servlet.AsyncContext;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 异步读取Servlet
 */
@WebServlet(value = "/async.input", asyncSupported = true) // 默认情况下是不开启异步支持的
public class AsyncReadServlet extends HttpServlet {

    private class ServletReadListener implements ReadListener { // 异步数据读取
        private AsyncContext asyncContext;
        private ServletInputStream servletInputStream; // 异步读取由此触发

        public ServletReadListener(AsyncContext asyncContext, ServletInputStream servletInputStream) {
            this.asyncContext = asyncContext;
            this.servletInputStream = servletInputStream;
        }

        @Override
        public void onDataAvailable() throws IOException {  // 数据可以读取时触发
            try {
                TimeUnit.SECONDS.sleep(5); // 强制性的模拟延迟5秒
                StringBuilder builder = new StringBuilder(); // 实现数据的保存，“info=www.yootk.com”
                int len = -1; // 读取数据的标记
                byte temp[] = new byte[1024]; // 设置字节数组
                while (this.servletInputStream.isReady() && (len = this.servletInputStream.read(temp)) != -1) {
                    String data = new String(temp, 0, len); // 将字节数据变为字符串
                    builder.append(data); // 将接收到的数据保存在StringBuilder之中
                }
                String info = builder.toString().split("=")[1]; // 获取info参数的内容
                this.asyncContext.getRequest().setAttribute("message", "【ECHO】" + info); // 设置request属性
                this.asyncContext.dispatch("/test03_show.jsp");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onAllDataRead() throws IOException {
            System.out.println("【ServletReadListener.onAllDataRead()】所有的请求数据读取完毕。");
        }

        @Override
        public void onError(Throwable throwable) {
            System.out.println("【ServletReadListener.onError()】数据读取出错，" + throwable);
        }
    }

    @Override   // 进行GET请求的处理
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        if (req.isAsyncSupported()) { // 判断当前是否支持有异步请求处理能力
            AsyncContext asyncContext = req.startAsync(); // 创建异步处理的上下文对象
            ServletInputStream servletInputStream = req.getInputStream();
            servletInputStream.setReadListener(new ServletReadListener(asyncContext, servletInputStream));
        } else {
            resp.getWriter().println("<h1>骚蕊，我还不支持异步请求处理，请放过我吧！</h1>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
